library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity tb_reg_8x8 is
end tb_reg_8x8;

architecture BEH of tb_reg_8x8 is
    component reg_8x8
        Port ( clk : in  STD_LOGIC;
               wr : in  STD_LOGIC;
               rst : in  STD_LOGIC; 
               addr_in : in  STD_LOGIC_VECTOR (2 downto 0);
               data_in : in  STD_LOGIC_VECTOR (7 downto 0);
               addr_out1 : in  STD_LOGIC_VECTOR (2 downto 0);
               addr_out2 : in  STD_LOGIC_VECTOR (2 downto 0);
               data_out1 : out  STD_LOGIC_VECTOR (7 downto 0);
               data_out2 : out  STD_LOGIC_VECTOR (7 downto 0));
    end component;

    signal clk : STD_LOGIC := '0';
    signal wr : STD_LOGIC := '0';
    signal rst : STD_LOGIC := '0'; 
    signal addr_in : STD_LOGIC_VECTOR (2 downto 0) := (others => '0');
    signal data_in : STD_LOGIC_VECTOR (7 downto 0) := (others => '0');
    signal addr_out1 : STD_LOGIC_VECTOR (2 downto 0) := (others => '0');
    signal addr_out2 : STD_LOGIC_VECTOR (2 downto 0) := (others => '0');
    signal data_out1 : STD_LOGIC_VECTOR (7 downto 0);
    signal data_out2 : STD_LOGIC_VECTOR (7 downto 0);

    constant clk_period : time := 10 ns;

begin
    uut: reg_8x8
        Port map ( clk => clk,
                   wr => wr,
                   rst => rst, 
                   addr_in => addr_in,
                   data_in => data_in,
                   addr_out1 => addr_out1,
                   addr_out2 => addr_out2,
                   data_out1 => data_out1,
                   data_out2 => data_out2 );

    clk_process: process
    begin
        clk <= '0';
        wait for clk_period/2;
        clk <= '1';
        wait for clk_period/2;
    end process;

    stim_process: process
    begin
        -- Initialize
        wr <= '0';
        addr_in <= "000";
        data_in <= "00000000";
        addr_out1 <= "000";
        addr_out2 <= "000";
        rst <= '0';  -- сброс на низком уровне
        wait for clk_period;

        -- Release reset
        rst <= '1';  -- сброс на высоком уровне
        wait for clk_period;

        -- Write to register 0
        wr <= '1';
        addr_in <= "000";
        data_in <= "10101010";
        wait for clk_period;
        wr <= '0';

        -- Write to register 1
        wr <= '1';
        addr_in <= "001";
        data_in <= "11001100";
        wait for clk_period;
        wr <= '0';

        -- Write to register 2
        wr <= '1';
        addr_in <= "010";
        data_in <= "11110000";
        wait for clk_period;
        wr <= '0';

        -- Read from register 0
        addr_out1 <= "000";
        addr_out2 <= "001";
        wait for clk_period;
        assert data_out1 = "10101010" report "Error: data_out1 mismatch" severity error;
        assert data_out2 = "11001100" report "Error: data_out2 mismatch" severity error;

        -- Read from register 1
        addr_out1 <= "001";
        addr_out2 <= "010";
        wait for clk_period;
        assert data_out1 = "11001100" report "Error: data_out1 mismatch" severity error;
        assert data_out2 = "11110000" report "Error: data_out2 mismatch" severity error;

        -- Read from register 2
        addr_out1 <= "010";
        addr_out2 <= "000";
        wait for clk_period;
        assert data_out1 = "11110000" report "Error: data_out1 mismatch" severity error;
        assert data_out2 = "10101010" report "Error: data_out2 mismatch" severity error;

        -- Finish
        wait;
    end process;
end BEH;